<!DOCTYPE html>
<html>
  <head>
    <title>Choropleth Tutorial - Leaflet</title>

    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />

    <link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />

    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="" />
    <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin=""></script>

    <style>
      html,
      body {
        height: 100%;
        margin: 0;
      }
      #map {
        width: 600px;
        height: 400px;
      }
    </style>

    <style>
      #map {
        width: 800px;
        height: 500px;
      }
      .info {
        padding: 6px 8px;
        font: 14px/16px Arial, Helvetica, sans-serif;
        background: white;
        background: rgba(255, 255, 255, 0.8);
        box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
        border-radius: 5px;
      }
      .info h4 {
        margin: 0 0 5px;
        color: #777;
      }
      .legend {
        text-align: left;
        line-height: 18px;
        color: #555;
      }
      .legend i {
        width: 18px;
        height: 18px;
        float: left;
        margin-right: 8px;
        opacity: 0.7;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>

    <script type="text/javascript" src="us-states.js"></script>

    <script type="text/javascript">
      var map = L.map('map').setView([37.8, -96], 4)

      L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
        maxZoom: 18,
        attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, ' + 'Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
        // 使用灰度瓦片
        id: 'mapbox/light-v9',
        tileSize: 512,
        zoomOffset: -1
      }).addTo(map)

      // 自定义控件，显示鼠标悬停时的状态信息
      var info = L.control()

      info.onAdd = function (map) {
        // 创建一个类名为 info 的 div 元素
        this._div = L.DomUtil.create('div', 'info')
        // 更新控件
        this.update()
        return this._div
      }

      // 控件更新方法
      info.update = function (props) {
        this._div.innerHTML = '<h4>US Population Density</h4>' + (props ? '<b>' + props.name + '</b><br />' + props.density + ' people / mi<sup>2</sup>' : 'Hover over a state')
      }

      info.addTo(map)

      // 根据各州的人口密度返回不同的颜色
      function getColor(d) {
        return d > 1000 ? '#800026' :
          d > 500 ? '#BD0026' :
          d > 200 ? '#E31A1C' :
          d > 100 ? '#FC4E2A' :
          d > 50 ? '#FD8D3C' :
          d > 20 ? '#FEB24C' :
          d > 10 ? '#FED976' : '#FFEDA0'
      }

      // 样式函数
      function style(feature) {
        return {
          weight: 2,
          opacity: 1,
          color: 'white',
          dashArray: '3', // 虚线
          fillOpacity: 0.7,
          // 根据人口密度获取颜色
          fillColor: getColor(feature.properties.density)
        }
      }

      function highlightFeature(e) {
        // 通过 e.target 访问被悬停的图层
        var layer = e.target

        // 在图层上设置高亮效果
        layer.setStyle({
          weight: 5,
          color: '#666',
          dashArray: '', // 实线
          fillOpacity: 0.7
        })

        if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
          // 放到图层的顶层，对 IE、Opera 或 Edge 来说，在 mouseover 时使用 bringToFront 会有问题
          layer.bringToFront()
        }
        // 更新控件，传入 GeoJSON feature 的属性
        info.update(layer.feature.properties)
      }

      var geojson

      function resetHighlight(e) {
        // 将图层样式重置为默认状态，由 style 函数定义
        geojson.resetStyle(e.target)
        info.update()
      }

      function zoomToFeature(e) {
        map.fitBounds(e.target.getBounds())
      }

      function onEachFeature(feature, layer) {
        layer.on({
          mouseover: highlightFeature, // 鼠标移入事件
          mouseout: resetHighlight, // 鼠标移出事件
          click: zoomToFeature // 点击事件
        })
      }

      geojson = L.geoJson(statesData, {
        style: style,
        onEachFeature: onEachFeature
      }).addTo(map)

      map.attributionControl.addAttribution('Population data &copy; <a href="http://census.gov/">US Census Bureau</a>')

      // 创建带有图例的控件
      var legend = L.control({ position: 'bottomright' })

      legend.onAdd = function (map) {
        var div = L.DomUtil.create('div', 'info legend'),
          grades = [0, 10, 20, 50, 100, 200, 500, 1000],
          labels = [],
          from,
          to

        for (var i = 0; i < grades.length; i++) {
          from = grades[i]
          to = grades[i + 1]

          labels.push('<i style="background:' + getColor(from + 1) + '"></i> ' + from + (to ? '&ndash;' + to : '+'))
        }

        div.innerHTML = labels.join('<br>')
        return div
      }

      legend.addTo(map)
    </script>
  </body>
</html>
